
        ;;
        ;; Native 64 bit assembler for the swarm code.
        ;; 

section .text

        ;; Global stuff
global _sw_distance:function
global _sw_vec_add:function
global _sw_vec_sub:function
global _sw_vec_scale:function
        
        ;; Functions here

	;;
	;; _sw_distance calculates the distance between two points held
        ;; by two 64 bit floating point types.
        ;; C prototype:
        ;;      void _sw_distance(sw_xmm_vec *, sw_xmm_vec *, double *);
        ;; 

_sw_distance:
	movupd xmm0, [rdi]	; load first point
	movupd xmm1, [rsi]	; load second point

	subpd  xmm0, xmm1
	mulpd  xmm0, xmm0
	
	sub rsp, 16
	movupd [rsp], xmm0	
	addsd  xmm0, [rsp+8]
	sqrtsd xmm0, xmm0
	movsd  [rdx], xmm0

	add rsp, 16
	ret
	
	;;
	;; _sw_vec_add adds two 2d xmm vectors pointed to by the args. The
	;; added value of the vectors is stored in the first vector.
	;; C prototype:
	;;	void _sw_vec_add(sw_xmm_vec *, sw_xmm_vec *);
	;;
	
_sw_vec_add:
	movapd xmm0, [rdi]	; load first point
	addpd  xmm0, [rsi]	; add second to it
	movapd [rdi], xmm0
	ret

	;;
	;; _sw_vec_sub subtractss two 2d xmm vectors pointed to by the args. The
	;; subtracteded value of the vectors is stored in the first vector.
	;; C prototype:
	;;	void _sw_vec_add(sw_xmm_vec *, sw_xmm_vec *);
	;;
	
_sw_vec_sub:
	movapd xmm0, [rdi]	; load first point
	subpd  xmm0, [rsi]	; sub second from it
	movapd [rdi], xmm0
	ret

	
	;;
	;; _sw_vec_scale scales a vector by the passed value.
	;; C prototype:
	;;	void _sw_vec_scale(sw_xmm_vec *, double *);
	;;
	
_sw_vec_scale:
	mov    rax, [rsi]
	mov    [rsp-16], rax
	mov    [rsp-8], rax
	
	movupd xmm0, [rsp-16]
	mulpd  xmm0, [rdi]
	movapd [rdi], xmm0

	ret
	